/* Nick Registration
Cvars:
	amx_nr_active (1) - 1/0 - wlacza/wylacza plugin

	amx_nr_info ("nr_pw") - info wymagane w konfigu (setinfo "info" "haslo")
	
	amx_nr_type (1) - typ rejestracji
			1 - automatyczne
			2 - tylko przez admina
			
	amx_nr_passtime (30) - ile sekund czekamy na haslo (minimum 15 maximum 60)
	
	amx_nr_url ("www.twoje_forum.com") - adres forum
	
	amx_nr_config ("") - jesli bedzei podany to u gracza zostanie zaipsany dodatkowy konfig
	
*/

#include <amxmodx>
#include <amxmisc>
#include <nvault>

#define PLUGIN "Rejestracja nickow"
#define VERSION "1.0"
#define AUTHOR "Tequila aka Zabijaka"
#define LEN_NAME 32
#define LEN_PASS 16
#define TASK_SAVE_CFG 200
#define TASK_CHECK 300
#define TASK_WAIT_FOR_PASS 100


new gCvarType;
new gCvarActive;
new gCvarInfo;
new gCvarUrl;
new gCvarPassTime;
new gCvarConfig;

new gVault;
new gInfoName[16];
new playerNames[33][LEN_NAME];
new playerIsRegistering[33];
new playerIsLoggedIn[33];
new playerIsOnServer[33];
new playerSpawns[33];
new gUrl[128];
new gConfig[32];
new adminNickRegister[33][LEN_NAME];

public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR);
	gCvarActive = register_cvar("amx_nr_active", "1");
	gCvarType = register_cvar("amx_nr_type", "1");
	gCvarInfo = register_cvar("amx_nr_info", "nr_pw");
	gCvarPassTime = register_cvar("amx_nr_passtime", "30");
	gCvarUrl =  register_cvar("amx_nr_url", "www.twoje_forum.com");
	gCvarConfig= register_cvar("amx_nr_config", "");
	
	gVault = nvault_open("NickRegister");
	
	register_clcmd("amx_nr_haslo", "podajHaslo");
	register_clcmd("amx_nr_menu", "nickRegisterMenu");
	register_clcmd("say \nickmenu", "nickRegisterMenu");
	register_clcmd("amx_nr_adminmenu", "nickRegisterAdminMenu", ADMIN_BAN);
	register_clcmd("amx_nr_showpass", "showPass", ADMIN_BAN);
	register_clcmd("amx_nr_nick", "nickRegisterAdmin", ADMIN_BAN);
	
	new cfgFolder[128];
	get_configsdir(cfgFolder, charsmax(cfgFolder));
	new cfgFile[128];
	formatex(cfgFile, charsmax(cfgFile), "%s\nickreg\nickreg.cfg", cfgFolder);
	server_cmd("exec %s", cfgFile);
}


public plugin_cfg() {
	get_pcvar_string(gCvarInfo, gInfoName, charsmax(gInfoName));
	get_pcvar_string(gCvarUrl, gUrl, charsmax(gUrl));
	get_pcvar_string(gCvarConfig, gConfig, charsmax(gConfig));
}

public checkPass(taskInfo[]){
	new id = taskInfo[0];
	if(!get_pcvar_num(gCvarActive))
		return;
	if(!is_user_connected(id) || is_user_bot(id) || is_user_hltv(id)){
		return;
	}
	
	new nameUpper[LEN_NAME];
	copy(nameUpper, LEN_NAME-1, playerNames[id]);
	strtoupper(nameUpper);
	
	new passVault[LEN_PASS];
	new passPlayer[LEN_PASS];
	
	
	new timestamp;
	
	if(nvault_lookup(gVault, nameUpper, passVault, LEN_PASS -1, timestamp)){
		get_user_info(id, gInfoName, passPlayer, LEN_PASS -1);
		if(!equal(passVault, passPlayer)){
			client_print(id, print_console, "====================================================================");
			client_print(id, print_console, "Nick %s jest zabezpieczony haslem", playerNames[id]);
			client_print(id, print_console, "Aby wejsc na serwer wpisz w konsoli:")
			client_print(id, print_console, "setinfo ^"%s^" ^"twoje haslo^"", gInfoName);
			client_print(id, print_console, "Jesli to Twoj a nie masz do niego hasla, wyjasnij to na %s", gUrl);
			client_print(id, print_console, "====================================================================");
			server_cmd("kick #%d ^"Nick zabezpieczony haslem. Sprawdz konsole.^"", get_user_userid(id));
		} else {
			playerIsLoggedIn[id]  = 1;
		}
	} else {
		if(get_pcvar_num(gCvarType) == 1){
			registerNick(id, playerNames[id]);
		} else {
			playerIsLoggedIn[id] = 2;
		}
	}

}
public client_putinserver(id) {
	if(!get_pcvar_num(gCvarActive))
		return;
	if(!is_user_connected(id) || is_user_bot(id) || is_user_hltv(id)){
		return;
	}
	get_user_name(id, playerNames[id], LEN_NAME -1);
	userNameChanged(id);
}
stock userNameChanged(id){
	
	playerIsOnServer[id] = 1;
	playerIsRegistering[id] = 0;
	playerIsLoggedIn[id] = 0;
	adminNickRegister[id][0] = 0;
	playerSpawns[0] = 0;
	playerNames[id][0] = 0;
	
	if(gConfig[0]) {
		client_cmd(id, "exec %s.cfg", gConfig);
		client_cmd(id, "exec config.cfg");
	}
	new taskInfo[2];
	taskInfo[0] = id;
	set_task(5.0,"checkPass", id+TASK_CHECK, taskInfo, 2);
}
public registerNick(id, const nick[]) {
	new motd[1200];
	
	new lenMax = charsmax(motd);
	new len = formatex(motd, lenMax, "<html><body style=^"background-color: black^">");
	len+= formatex(motd[len], lenMax-len,"<h1 style=^"color: red^">Rejestracja Nicku</h1>");
	len+= formatex(motd[len], lenMax-len,"<h2 style=^"color: #00FF66^">Na tym serwerze prowadzona jest rejestracja nickow.<br/>");
	len+= formatex(motd[len], lenMax-len,"Za chwile zostaniesz poproszony o podanie hasla.<br/>");
	len+= formatex(motd[len], lenMax-len,"Od tej chwili bedzie ono wymagane aby grac na nicku ^"%s^"</br>", nick);
	len+= formatex(motd[len], lenMax-len,"Informacja zostanie dodana do twojego konfiga.<br/>");
	len+= formatex(motd[len], lenMax-len,"Jesli mimo to nie bedziesz mogl wejsc na serwer<br/>");
	len+= formatex(motd[len], lenMax-len,"upewnij sie ze masz wpisane &lt;setinfo ^"%s^" ^"twoje haslo^"&gt; (bez &lt;&gt;) w pliku config.cfg<br/>", gInfoName);
	len+= formatex(motd[len], lenMax-len,"lub wpisz w konsoli setinfo ^"%s^" ^"twoje haslo^"<br/>", gInfoName);
	len+= formatex(motd[len], lenMax-len,"</h2></body></html>");
	
	show_motd(id, motd);
	playerIsRegistering[id] = 1;
	client_cmd(id, "amx_nr_menu");
}

public podajHaslo(id){
	if(!get_pcvar_num(gCvarActive))
		return PLUGIN_CONTINUE;
	
	new isAdminRegister = adminNickRegister[id][0];
	
	if(playerIsRegistering[id]  || playerIsLoggedIn[id] ==1 || isAdminRegister){
		new haslo[LEN_PASS];
		read_argv(1, haslo, LEN_PASS-1);
		remove_quotes(haslo);
		new name[LEN_NAME];
		new nameUpper[LEN_NAME];
		if(isAdminRegister)
			copy(name, LEN_NAME -1, adminNickRegister[id]);
		else
			copy(name, LEN_NAME -1, playerNames[id]);
		copy(nameUpper, LEN_NAME -1, name);
		strtoupper(nameUpper);
		
		if(strlen(haslo) > 5){
			nvault_set(gVault, nameUpper, haslo);
			if(!isAdminRegister) {
				client_cmd(id, "setinfo ^"%s^" ^"%s^"", gInfoName, haslo);
				if(gConfig[0]){
					new taskInfo[2];
					taskInfo[0] = id;
					set_task(0.2,"saveConfig", id + TASK_SAVE_CFG, taskInfo, 2);
				}
				playerIsLoggedIn[id] = 1;
				if(task_exists(id + TASK_WAIT_FOR_PASS)){
					remove_task(id +TASK_WAIT_FOR_PASS);
				}
				showPassMotd(id, name, haslo);
			}else {
				client_print(id, print_console, "Haslo dla nicku %s to %s", name, haslo);
				client_print(id, print_chat, "Haslo dla nicku %s to %s", name, haslo);
				adminNickRegister[id][0] = 0;
			}
			
		} else {
			client_print(id, print_chat, "Haslo musi miec wiecej niz 5 znakow.");
			client_cmd(id, "messagemode amx_nr_haslo");
		}
	}
	return PLUGIN_HANDLED;
}

public saveConfig(taskInfo[]){
	new id = taskInfo[0];
	if(is_user_connected(id)){
		client_cmd(id, "writecfg %s", gConfig);
	}
}

stock showPassMotd(id, const name[], const pass[]){
	new motd[1200];
	
	new lenMax = charsmax(motd);
	new len = formatex(motd, lenMax, "<html><body style=^"background-color: black^">");
	len+= formatex(motd[len], lenMax-len,"<h1 style=^"color: red^">Rejestracja Nicku</h1>");
	len+= formatex(motd[len], lenMax-len,"<h2 style=^"color: #00FF66^">Nick ^"%s^" zostal zabezpieczony haslem %s.", name, pass);
	len+= formatex(motd[len], lenMax-len,"Informacja zostala dodana do Twojego konfiga.<br/>");
	len+= formatex(motd[len], lenMax-len,"Jesli mimo to nie bedziesz mogl wejsc na serwer<br/>");
	len+= formatex(motd[len], lenMax-len,"upewnij sie ze masz wpisane &lt;setinfo ^"%s^" ^"%s^"&gt; (bez &lt;&gt;) w pliku config.cfg<br/>", gInfoName, pass);
	len+= formatex(motd[len], lenMax-len,"lub wpisz w konsoli setinfo ^"%s^" ^"%s^"</br>", gInfoName, pass);
	len+= formatex(motd[len], lenMax-len,"</h2></body></html>");
	show_motd(id, motd);
}

public nickRegisterMenu(id){
	if(!get_pcvar_num(gCvarActive))
		return PLUGIN_CONTINUE;
		
	new menu = menu_create("Rejestracja nicku", "nickRegisterMenuHandler");
	new key[2];
	menu_setprop(menu, MPROP_PERPAGE, 0);
	
	if(playerIsRegistering[id]){
		key[0] =1;
		menu_additem(menu, "Ustal haslo", key);
	} 
	
	if(playerIsLoggedIn[id]){
		key[0] = 2;
		menu_additem(menu, "Zmien haslo", key);
		menu_addblank(menu, 0);
		menu_addblank(menu, 0);
		menu_addblank(menu, 0);
		key[0] = 3;
		menu_additem(menu, "Wyjdz", key);
	}
	
	menu_display(id, menu);
	return PLUGIN_HANDLED;
}

public nickRegisterMenuHandler(id, menu, item){
	new key[2];
	new acc, call;
	menu_item_getinfo(menu, item, acc, key, 2, _,_, call);
	new taskInfo[3];
	taskInfo[0] = id;
	taskInfo[1] =  get_pcvar_num(gCvarPassTime);
	
	if(taskInfo[1] <15)
		taskInfo[1] = 15;
	else if (taskInfo[1] >60)
		taskInfo[1] = 60;
		
	switch(key[0]){
		case 1:{
			set_task(0.01, "taskWaitForPass", id + TASK_WAIT_FOR_PASS, taskInfo, 2);
			client_cmd(id, "messagemode amx_nr_haslo");
		}
		case 2:{
			client_cmd(id, "messagemode amx_nr_haslo");
		}
		case 3:{
			menu_destroy(menu);
		}
	}
	return PLUGIN_HANDLED;
}


public taskWaitForPass(taskInfo[]){
	new id = taskInfo[0];
	if(!is_user_connected(id))
		return;
	if(playerIsLoggedIn[id])
		return;
		
	new sec = taskInfo[2];
	if(sec == 0){
		client_print(id, print_console, "Rejestracja nicku nie powiodla sie.");
		server_cmd("kick #%d ^"Rejestracja nicku nie powiodla sie.^"", get_user_userid(id));
	}
		
	set_hudmessage(0, 0, 255, -1.0, -1.0);
	show_hudmessage(id, "Pozostalo %d sekund na podanie hasla.", sec);
	taskInfo[1] = sec - 1;
	
	set_task(1.0, "taskWaitForPass", id + TASK_WAIT_FOR_PASS, taskInfo, 2);
}

public client_disconnect(id){
	if(task_exists(id + 100)){
		remove_task(id +100);
	}
	playerIsOnServer[id] = 0;
	return PLUGIN_CONTINUE;
}

public nickRegisterAdminMenu(id, level, cid){
	if(!get_pcvar_num(gCvarActive))
		return PLUGIN_CONTINUE;
	
	if(cmd_access(id, level, cid, 0)){
		adminMenu(id);
	}
	return PLUGIN_HANDLED;
	
}

public adminMenu(id){
	new menu = menu_create("Admin Nick Menu", "adminMenuHandler");
	new info[2];
	
	if(get_pcvar_num(gCvarType) != 1) { // 1 - rejestracja automatyczna
		info[0] = 1;
		menu_additem(menu, "Rejestruj nick gracza", info);
	}

	info[0] = 2;
	menu_additem(menu, "Rejestruj nick", info);

	info[0] = 3;
	menu_additem(menu, "Pokaz haslo nicku", info);
	
	menu_display(id, menu);
}


public adminMenuHandler(id, menu, item){
	if(item == MENU_EXIT) {
		menu_destroy(menu);
		return PLUGIN_HANDLED;
	}
	
	new key[2];
	new acc, call;
	menu_item_getinfo(menu, item, acc, key, 2, _,_, call);
	switch(key[0]){
		case 1:playerMenu(id);
		case 2:client_cmd(id, "messagemode amx_nr_nick");
		case 3:client_cmd(id, "messagemode amx_nr_showpass");
	
	}
	return PLUGIN_HANDLED;
}

public nickRegisterAdmin(id, level, cid){
	if(!get_pcvar_num(gCvarActive)){
		return PLUGIN_CONTINUE;
	}
	if(cmd_access(id,level,cid, 1)){
		new name[LEN_NAME];
		read_argv(1, name, LEN_NAME-1);
		remove_quotes(name);
		new nameUpper[LEN_NAME];
		copy(nameUpper, LEN_NAME-1, name);
		strtoupper(nameUpper);
		new haslo[LEN_PASS];
		new timestamp;
		
		if(nvault_lookup(gVault, nameUpper, haslo, LEN_PASS-1, timestamp)){
			client_print(id, print_chat, "Nick %s jest juz zarejestrowany.", name);
			client_print(id, print_console, "Nick %s jest juz zarejestrowany.", name);
		} else {
			copy(adminNickRegister[id], LEN_NAME-1, name);
			client_cmd(id, "messagemoed amx_nr_haslo");
		}
	}
	return PLUGIN_HANDLED;
}
stock playerMenu(id) {
	new players[32];
	new num;
	get_players(players, num, "ch");
	new menu = menu_create("Rajestracja nickow", "registerPlayerNickMenuHandler");
		
	new player;
	new key[2];
	for(new i=0;i<num;i++){
		player = players[i];
		if(playerIsLoggedIn[player] != 1 && !playerIsRegistering[player]){
			key[0] =  player;
			menu_additem(menu, playerNames[player], key);
		}
	}
	menu_display(id, menu);
}


public registerPlayerNickMenuHandler(id, menu, item){
	if(item == MENU_EXIT){
		menu_destroy(menu);
		return PLUGIN_HANDLED;
	}
	new key[2];
	new acc, call;
	menu_item_getinfo(menu, item, acc, key, 2, _,_, call);
	new player = key[0];
	if(is_user_connected(player)){
		registerNick(player, playerNames[player]);
	}
	menu_destroy(menu);
	return PLUGIN_HANDLED;
}


public client_infochanged(id){
	if(!get_pcvar_num(gCvarActive))
		return;
	if(!playerIsOnServer[id])
		return;
	if(!is_user_connected(id) || is_user_bot(id) || is_user_hltv(id))
		return;
		
	
	new name[LEN_NAME];
	get_user_info(id, "name", name, LEN_NAME-1);
	if(!equal(name, playerNames[id])){
		copy(playerNames[id], LEN_NAME-1, name);
		userNameChanged(id);
	}
}

public showPass(id, level,cid){
	if(!get_pcvar_num(gCvarActive)){
		return PLUGIN_CONTINUE;
	}
	if(cmd_access(id,level,cid, 1)){
		new name[LEN_NAME];
		read_argv(1, name, LEN_NAME-1);
		remove_quotes(name);
		new nameUpper[LEN_NAME];
		copy(nameUpper, LEN_NAME-1, name);
		strtoupper(nameUpper);
		new haslo[LEN_PASS];
		new timestamp;
		
		if(nvault_lookup(gVault, nameUpper, haslo, LEN_PASS-1, timestamp)){
			client_print(id, print_chat, "Haslo dla nicku %s to %s", name, haslo);
			client_print(id, print_console, "Haslo dla nicku %s to %s", name, haslo);
		} else {
			client_print(id, print_chat, "Nick %s nie jest zarejestrowany", name);
			client_print(id, print_console, "Nick %s nie jest zarejestrowany", name);
		}
	}
	return PLUGIN_HANDLED;
}


